package plus;

import java.util.*;

/**
 * This represents the arbitrary collection of field types, irrespective of any particular
 * type constructor. This therefore provides a convenient vehicle for both record prototypes
 * and value constructions - that is, "new Foo (bar:baz)"
 * 
 * @author Ian
 *
 */
public class Struct {
	Map<String, Type> proto = new TreeMap<String, Type>();
	Map<String, Integer> posn = new TreeMap<String, Integer>();
	List<String> names = new ArrayList<String>();

	public void introduce_field(String n, Type variable) {
		if (proto.containsKey(n)) throw new Gripe("duplicate field "+n);
		proto.put(n, variable);
		posn.put(n, names.size());
		names.add(n);
	}

	public boolean isNames(String[] names) {
		// this only works if all input names are unique.
		if (names.length != this.names.size()) return false;
		for (String n:names) if (!proto.containsKey(n)) return false;
		return true;
	}
	
	Type typeOf(String name, Type[] actuals) {
		Type plate = proto.get(name);
		if (plate == null) throw new Gripe("No such field "+name);
		return plate.chase().subst(actuals);
	}

	public int indexOfField(String name) { return posn.get(name); }

	public void reportExpected() {
		System.out.println("--- expected ---");
		for (String s:names) System.out.println("field: "+s);
	}
}
